plat/synquacer: enable SCMI support
authorMasahisa Kojima <[email protected]>
Thu, 7 Mar 2019 01:41:54 +0000 (10:41 +0900)
committerMasahisa Kojima <[email protected]>
Wed, 13 Mar 2019 00:54:15 +0000 (09:54 +0900)
Enable the SCMI protocol support in SynQuacer platform.
Aside from power domain, system power and apcore management protocol,
this commit adds the vendor specific protocol(0x80).
This vendor specific protocol is used to get the dram mapping information
from SCP.

Signed-off-by: Masahisa Kojima <[email protected]>
drivers/arm/css/scmi/scmi_private.h
drivers/arm/css/scmi/vendor/scmi_sq.c [new file with mode: 0644]
drivers/arm/css/scmi/vendor/scmi_sq.h [new file with mode: 0644]
plat/socionext/synquacer/drivers/scp/sq_scmi.c [new file with mode: 0644]
plat/socionext/synquacer/drivers/scp/sq_scp.c [new file with mode: 0644]
plat/socionext/synquacer/drivers/scpi/sq_scpi.h
plat/socionext/synquacer/include/platform_def.h
plat/socionext/synquacer/include/sq_common.h
plat/socionext/synquacer/platform.mk
plat/socionext/synquacer/sq_bl31_setup.c
plat/socionext/synquacer/sq_psci.c

index 65305736c7c7f43b971620f91216020f2ea79358..61437f6d7a443abab6dc00bce6dcbbced78894b0 100644 (file)
@@ -152,4 +152,9 @@ static inline void validate_scmi_channel(scmi_channel_t *ch)
        assert(ch->info && ch->info->scmi_mbx_mem);
 }
 
+/*
+ * SCMI vendor specific protocol
+ */
+#define SCMI_SYS_VENDOR_EXT_PROTO_ID           0x80
+
 #endif /* SCMI_PRIVATE_H */
diff --git a/drivers/arm/css/scmi/vendor/scmi_sq.c b/drivers/arm/css/scmi/vendor/scmi_sq.c
new file mode 100644 (file)
index 0000000..2ae7ca1
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/arm/css/scmi.h>
+
+#include "scmi_private.h"
+#include "scmi_sq.h"
+
+#include <sq_common.h>
+
+/* SCMI messge ID to get the available DRAM region */
+#define SCMI_VENDOR_EXT_MEMINFO_GET_MSG                0x3
+
+/*
+ * API to get the available DRAM region
+ */
+int scmi_get_draminfo(void *p, struct draminfo *info)
+{
+       mailbox_mem_t *mbx_mem;
+       int token = 0, ret;
+       scmi_channel_t *ch = (scmi_channel_t *)p;
+       struct dram_info_resp response;
+
+       validate_scmi_channel(ch);
+
+       scmi_get_channel(ch);
+
+       mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem);
+       mbx_mem->msg_header = SCMI_MSG_CREATE(SCMI_SYS_VENDOR_EXT_PROTO_ID,
+                       SCMI_VENDOR_EXT_MEMINFO_GET_MSG, token);
+       mbx_mem->len = 8;
+       mbx_mem->flags = SCMI_FLAG_RESP_POLL;
+
+       scmi_send_sync_command(ch);
+
+       /*
+        * Ensure that any read to the SCPI payload area is done after reading
+        * the MHU register. If these 2 reads were reordered then the CPU would
+        * read invalid payload data
+        */
+       dmbld();
+
+       /* Get the return values */
+       SCMI_PAYLOAD_RET_VAL1(mbx_mem->payload, ret);
+
+       memcpy(&response, (void *)mbx_mem->payload, sizeof(response));
+
+       scmi_put_channel(ch);
+
+       *info = response.info;
+
+       return ret;
+}
diff --git a/drivers/arm/css/scmi/vendor/scmi_sq.h b/drivers/arm/css/scmi/vendor/scmi_sq.h
new file mode 100644 (file)
index 0000000..aee1a3a
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SCMI_SQ_H
+#define SCMI_SQ_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <sq_common.h>
+
+/* Structure to represent available DRAM region */
+struct dram_info_resp {
+       int status;
+       int reserved;
+       struct draminfo info;
+};
+
+/* API to get the available DRAM region */
+int scmi_get_draminfo(void *p, struct draminfo *info);
+
+#endif /* SCMI_SQ_H */
diff --git a/plat/socionext/synquacer/drivers/scp/sq_scmi.c b/plat/socionext/synquacer/drivers/scp/sq_scmi.c
new file mode 100644 (file)
index 0000000..e2013cc
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/arm/css/css_mhu_doorbell.h>
+#include <drivers/arm/css/css_scp.h>
+#include <drivers/arm/css/scmi.h>
+#include <plat/arm/css/common/css_pm.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include <scmi_sq.h>
+#include <sq_common.h>
+
+/*
+ * This file implements the SCP helper functions using SCMI protocol.
+ */
+
+DEFINE_BAKERY_LOCK(sq_scmi_lock);
+#define SQ_SCMI_LOCK_GET_INSTANCE      (&sq_scmi_lock)
+
+#define SQ_SCMI_PAYLOAD_BASE           PLAT_SQ_SCP_COM_SHARED_MEM_BASE
+#define MHU_CPU_INTR_S_SET_OFFSET      0x308
+
+const uint32_t sq_core_pos_to_scmi_dmn_id_map[PLATFORM_CORE_COUNT] = {
+       0,   1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11,
+       12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23
+};
+
+static scmi_channel_plat_info_t sq_scmi_plat_info = {
+               .scmi_mbx_mem = SQ_SCMI_PAYLOAD_BASE,
+               .db_reg_addr = PLAT_SQ_MHU_BASE + MHU_CPU_INTR_S_SET_OFFSET,
+               .db_preserve_mask = 0xfffffffe,
+               .db_modify_mask = 0x1,
+               .ring_doorbell = &mhu_ring_doorbell,
+};
+
+/*
+ * SCMI power state parameter bit field encoding for SynQuacer platform.
+ *
+ * 31  20 19       16 15      12 11       8 7        4 3         0
+ * +-------------------------------------------------------------+
+ * | SBZ | Max level |  Level 3 |  Level 2 |  Level 1 |  Level 0 |
+ * |     |           |   state  |   state  |   state  |   state  |
+ * +-------------------------------------------------------------+
+ *
+ * `Max level` encodes the highest level that has a valid power state
+ * encoded in the power state.
+ */
+#define SCMI_PWR_STATE_MAX_PWR_LVL_SHIFT       16
+#define SCMI_PWR_STATE_MAX_PWR_LVL_WIDTH       4
+#define SCMI_PWR_STATE_MAX_PWR_LVL_MASK                \
+                               ((1 << SCMI_PWR_STATE_MAX_PWR_LVL_WIDTH) - 1)
+#define SCMI_SET_PWR_STATE_MAX_PWR_LVL(_power_state, _max_level)               \
+               (_power_state) |= ((_max_level) & SCMI_PWR_STATE_MAX_PWR_LVL_MASK)\
+                               << SCMI_PWR_STATE_MAX_PWR_LVL_SHIFT
+#define SCMI_GET_PWR_STATE_MAX_PWR_LVL(_power_state)           \
+               (((_power_state) >> SCMI_PWR_STATE_MAX_PWR_LVL_SHIFT)   \
+                               & SCMI_PWR_STATE_MAX_PWR_LVL_MASK)
+
+#define SCMI_PWR_STATE_LVL_WIDTH               4
+#define SCMI_PWR_STATE_LVL_MASK                        \
+                               ((1 << SCMI_PWR_STATE_LVL_WIDTH) - 1)
+#define SCMI_SET_PWR_STATE_LVL(_power_state, _level, _level_state)             \
+               (_power_state) |= ((_level_state) & SCMI_PWR_STATE_LVL_MASK)    \
+                               << (SCMI_PWR_STATE_LVL_WIDTH * (_level))
+#define SCMI_GET_PWR_STATE_LVL(_power_state, _level)           \
+               (((_power_state) >> (SCMI_PWR_STATE_LVL_WIDTH * (_level))) &    \
+                               SCMI_PWR_STATE_LVL_MASK)
+
+/*
+ * The SCMI power state enumeration for a power domain level
+ */
+typedef enum {
+       scmi_power_state_off = 0,
+       scmi_power_state_on = 1,
+       scmi_power_state_sleep = 2,
+} scmi_power_state_t;
+
+/*
+ * The global handle for invoking the SCMI driver APIs after the driver
+ * has been initialized.
+ */
+static void *sq_scmi_handle;
+
+/* The SCMI channel global object */
+static scmi_channel_t channel;
+
+/*
+ * Helper function to turn off a CPU power domain and
+ * its parent power domains if applicable.
+ */
+void sq_scmi_off(const struct psci_power_state *target_state)
+{
+       int lvl = 0, ret;
+       uint32_t scmi_pwr_state = 0;
+
+       /* At-least the CPU level should be specified to be OFF */
+       assert(target_state->pwr_domain_state[SQ_PWR_LVL0] ==
+                                                       SQ_LOCAL_STATE_OFF);
+
+       for (; lvl <= PLAT_MAX_PWR_LVL; lvl++) {
+               if (target_state->pwr_domain_state[lvl] == SQ_LOCAL_STATE_RUN)
+                       break;
+
+               assert(target_state->pwr_domain_state[lvl] ==
+                                                       SQ_LOCAL_STATE_OFF);
+               SCMI_SET_PWR_STATE_LVL(scmi_pwr_state, lvl,
+                               scmi_power_state_off);
+       }
+
+       SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1);
+
+       ret = scmi_pwr_state_set(sq_scmi_handle,
+               sq_core_pos_to_scmi_dmn_id_map[plat_my_core_pos()],
+               scmi_pwr_state);
+
+       if (ret != SCMI_E_QUEUED && ret != SCMI_E_SUCCESS) {
+               ERROR("SCMI set power state command return 0x%x unexpected\n",
+                               ret);
+               panic();
+       }
+}
+
+/*
+ * Helper function to turn ON a CPU power domain and
+ *its parent power domains if applicable.
+ */
+void sq_scmi_on(u_register_t mpidr)
+{
+       int lvl = 0, ret, core_pos;
+       uint32_t scmi_pwr_state = 0;
+
+       for (; lvl <= PLAT_MAX_PWR_LVL; lvl++)
+               SCMI_SET_PWR_STATE_LVL(scmi_pwr_state, lvl,
+                               scmi_power_state_on);
+
+       SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1);
+
+       core_pos = plat_core_pos_by_mpidr(mpidr);
+       assert(core_pos >= 0 && core_pos < PLATFORM_CORE_COUNT);
+
+       ret = scmi_pwr_state_set(sq_scmi_handle,
+               sq_core_pos_to_scmi_dmn_id_map[core_pos],
+               scmi_pwr_state);
+
+       if (ret != SCMI_E_QUEUED && ret != SCMI_E_SUCCESS) {
+               ERROR("SCMI set power state command return 0x%x unexpected\n",
+                               ret);
+               panic();
+       }
+}
+
+void __dead2 sq_scmi_system_off(int state)
+{
+       int ret;
+
+       /*
+        * Disable GIC CPU interface to prevent pending interrupt from waking
+        * up the AP from WFI.
+        */
+       sq_gic_cpuif_disable();
+
+       /*
+        * Issue SCMI command. First issue a graceful
+        * request and if that fails force the request.
+        */
+       ret = scmi_sys_pwr_state_set(sq_scmi_handle,
+                       SCMI_SYS_PWR_FORCEFUL_REQ,
+                       state);
+
+       if (ret != SCMI_E_SUCCESS) {
+               ERROR("SCMI system power state set 0x%x returns unexpected 0x%x\n",
+                       state, ret);
+               panic();
+       }
+       wfi();
+       ERROR("SCMI set power state: operation not handled.\n");
+       panic();
+}
+
+/*
+ * Helper function to reset the system via SCMI.
+ */
+void __dead2 sq_scmi_sys_reboot(void)
+{
+       sq_scmi_system_off(SCMI_SYS_PWR_COLD_RESET);
+}
+
+static int scmi_ap_core_init(scmi_channel_t *ch)
+{
+#if PROGRAMMABLE_RESET_ADDRESS
+       uint32_t version;
+       int ret;
+
+       ret = scmi_proto_version(ch, SCMI_AP_CORE_PROTO_ID, &version);
+       if (ret != SCMI_E_SUCCESS) {
+               WARN("SCMI AP core protocol version message failed\n");
+               return -1;
+       }
+
+       if (!is_scmi_version_compatible(SCMI_AP_CORE_PROTO_VER, version)) {
+               WARN("SCMI AP core protocol version 0x%x incompatible with driver version 0x%x\n",
+                                               version, SCMI_AP_CORE_PROTO_VER);
+               return -1;
+       }
+       INFO("SCMI AP core protocol version 0x%x detected\n", version);
+#endif
+       return 0;
+}
+
+void __init plat_sq_pwrc_setup(void)
+{
+       channel.info = &sq_scmi_plat_info;
+       channel.lock = SQ_SCMI_LOCK_GET_INSTANCE;
+       sq_scmi_handle = scmi_init(&channel);
+       if (sq_scmi_handle == NULL) {
+               ERROR("SCMI Initialization failed\n");
+               panic();
+       }
+       if (scmi_ap_core_init(&channel) < 0) {
+               ERROR("SCMI AP core protocol initialization failed\n");
+               panic();
+       }
+}
+
+uint32_t sq_scmi_get_draminfo(struct draminfo *info)
+{
+       scmi_get_draminfo(sq_scmi_handle, info);
+
+       return 0;
+}
diff --git a/plat/socionext/synquacer/drivers/scp/sq_scp.c b/plat/socionext/synquacer/drivers/scp/sq_scp.c
new file mode 100644 (file)
index 0000000..e494022
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <sq_common.h>
+#include "sq_scpi.h"
+
+/*
+ * Helper function to get dram information from SCP.
+ */
+uint32_t sq_scp_get_draminfo(struct draminfo *info)
+{
+#if SQ_USE_SCMI_DRIVER
+       sq_scmi_get_draminfo(info);
+#else
+       scpi_get_draminfo(info);
+#endif
+       return 0;
+}
index 38cc19e5c8b4b1e45777b2e68f599f25ddd146b7..eb6ce5c91c06850dea4221307c1127f30db8f659 100644 (file)
@@ -78,5 +78,6 @@ extern void scpi_set_sq_power_state(unsigned int mpidr,
                                        scpi_power_state_t cluster_state,
                                        scpi_power_state_t css_state);
 uint32_t scpi_sys_power_state(scpi_system_state_t system_state);
+uint32_t scpi_get_draminfo(struct draminfo *info);
 
 #endif /* SQ_SCPI_H */
index 0cec81b8d0dce67aec7191422cb15bd98424b740..263b215f2abbea51cb1cd94d60829a46e59e3b3e 100644 (file)
 #define PLATFORM_CORE_COUNT            (PLAT_CLUSTER_COUNT *   \
                                         PLAT_MAX_CORES_PER_CLUSTER)
 
+/* Macros to read the SQ power domain state */
+#define SQ_PWR_LVL0            MPIDR_AFFLVL0
+#define SQ_PWR_LVL1            MPIDR_AFFLVL1
+#define SQ_PWR_LVL2            MPIDR_AFFLVL2
+
+#define SQ_CORE_PWR_STATE(state)       (state)->pwr_domain_state[SQ_PWR_LVL0]
+#define SQ_CLUSTER_PWR_STATE(state)    (state)->pwr_domain_state[SQ_PWR_LVL1]
+#define SQ_SYSTEM_PWR_STATE(state)     ((PLAT_MAX_PWR_LVL > SQ_PWR_LVL1) ?\
+                               (state)->pwr_domain_state[SQ_PWR_LVL2] : 0)
+
 #define PLAT_MAX_PWR_LVL               U(1)
 #define PLAT_MAX_RET_STATE             U(1)
 #define PLAT_MAX_OFF_STATE             U(2)
@@ -70,6 +80,7 @@
 #define DRAMINFO_BASE                  0x2E00FFC0
 
 #define PLAT_SQ_MHU_BASE               0x45000000
+#define PLAT_CSS_MHU_BASE              PLAT_SQ_MHU_BASE
 
 #define PLAT_SQ_SCP_COM_SHARED_MEM_BASE                0x45400000
 #define SCPI_CMD_GET_DRAMINFO                  0x1
index abd90904d75a5788fb771da5303e918ec6b883d8..a9858229f3d99900ab73ac3bc634d81e8cb4fe9b 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <stdint.h>
 
+#include <lib/psci/psci.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 
 struct draminfo {
@@ -22,7 +23,7 @@ struct draminfo {
        uint64_t        size3;
 };
 
-uint32_t scpi_get_draminfo(struct draminfo *info);
+uint32_t sq_scp_get_draminfo(struct draminfo *info);
 
 void plat_sq_pwrc_setup(void);
 
@@ -41,4 +42,12 @@ void sq_gic_pcpu_init(void);
 void sq_mmap_setup(uintptr_t total_base, size_t total_size,
                   const struct mmap_region *mmap);
 
+/* SCMI API for power management by SCP */
+void sq_scmi_off(const struct psci_power_state *target_state);
+void sq_scmi_on(u_register_t mpidr);
+void __dead2 sq_scmi_sys_reboot(void);
+void __dead2 sq_scmi_system_off(int state);
+/* SCMI API for vendor specific protocol */
+uint32_t sq_scmi_get_draminfo(struct draminfo *info);
+
 #endif /* SQ_COMMON_H */
index 53c39a0fc9c87ffac15710ed126bd3498d450fb5..f5e72cb6441309bbbe168d6ad16ab78f1115af75 100644 (file)
@@ -10,9 +10,10 @@ override PROGRAMMABLE_RESET_ADDRESS  := 1
 override USE_COHERENT_MEM              := 1
 override SEPARATE_CODE_AND_RODATA      := 1
 override ENABLE_SVE_FOR_NS             := 0
-
 # Enable workarounds for selected Cortex-A53 erratas.
 ERRATA_A53_855873              := 1
+# Enable SCMI support
+SQ_USE_SCMI_DRIVER             ?= 0
 
 # Libraries
 include lib/xlat_tables_v2/xlat_tables.mk
@@ -20,7 +21,9 @@ include lib/xlat_tables_v2/xlat_tables.mk
 PLAT_PATH              :=      plat/socionext/synquacer
 PLAT_INCLUDES          :=      -I$(PLAT_PATH)/include          \
                                -I$(PLAT_PATH)/drivers/scpi     \
-                               -I$(PLAT_PATH)/drivers/mhu
+                               -I$(PLAT_PATH)/drivers/mhu \
+                               -Idrivers/arm/css/scmi \
+                               -Idrivers/arm/css/scmi/vendor
 
 PLAT_BL_COMMON_SOURCES +=      $(PLAT_PATH)/sq_helpers.S               \
                                drivers/arm/pl011/aarch64/pl011_console.S \
@@ -40,12 +43,27 @@ BL31_SOURCES                +=      drivers/arm/ccn/ccn.c                   \
                                $(PLAT_PATH)/sq_topology.c              \
                                $(PLAT_PATH)/sq_psci.c                  \
                                $(PLAT_PATH)/sq_gicv3.c                 \
-                               $(PLAT_PATH)/sq_xlat_setup.c            \
-                               $(PLAT_PATH)/drivers/scpi/sq_scpi.c     \
+                               $(PLAT_PATH)/sq_xlat_setup.c    \
+                               $(PLAT_PATH)/drivers/scp/sq_scp.c
+
+ifeq (${SQ_USE_SCMI_DRIVER},0)
+BL31_SOURCES           +=      $(PLAT_PATH)/drivers/scpi/sq_scpi.c     \
                                $(PLAT_PATH)/drivers/mhu/sq_mhu.c
+else
+BL31_SOURCES           +=      $(PLAT_PATH)/drivers/scp/sq_scmi.c              \
+                               drivers/arm/css/scmi/scmi_common.c              \
+                               drivers/arm/css/scmi/scmi_pwr_dmn_proto.c       \
+                               drivers/arm/css/scmi/scmi_sys_pwr_proto.c       \
+                               drivers/arm/css/scmi/vendor/scmi_sq.c   \
+                               drivers/arm/css/mhu/css_mhu_doorbell.c
+endif
 
 ifeq (${ENABLE_SPM},1)
 $(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
 
 BL31_SOURCES           +=      $(PLAT_PATH)/sq_spm.c
 endif
+
+ifeq (${SQ_USE_SCMI_DRIVER},1)
+$(eval $(call add_define,SQ_USE_SCMI_DRIVER))
+endif
index fef84efd7d8238d644466aaf812ad2bbe1092faf..c78fe91881bfe1b701846c78d9fac14daaf4bea5 100644 (file)
@@ -14,7 +14,6 @@
 #include <common/debug.h>
 #include <drivers/arm/pl011.h>
 #include <lib/mmio.h>
-
 #include <sq_common.h>
 
 static console_pl011_t console;
@@ -83,7 +82,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 #ifdef SPD_opteed
        struct draminfo di = {0};
 
-       scpi_get_draminfo(&di);
+       sq_scp_get_draminfo(&di);
 
        /*
         * Check if OP-TEE has been loaded in Secure RAM allocated
@@ -154,7 +153,7 @@ void bl31_plat_runtime_setup(void)
 {
        struct draminfo *di = (struct draminfo *)(unsigned long)DRAMINFO_BASE;
 
-       scpi_get_draminfo(di);
+       sq_scp_get_draminfo(di);
 }
 
 void bl31_plat_arch_setup(void)
index 134224dce64ab1ed7ef9a0ab7f8b2516bb13b300..731b19a323038e6a9ec9240dc14692b5571c7494 100644 (file)
 #include <sq_common.h>
 #include "sq_scpi.h"
 
-/* Macros to read the SQ power domain state */
-#define SQ_PWR_LVL0    MPIDR_AFFLVL0
-#define SQ_PWR_LVL1    MPIDR_AFFLVL1
-#define SQ_PWR_LVL2    MPIDR_AFFLVL2
-
-#define SQ_CORE_PWR_STATE(state)       (state)->pwr_domain_state[SQ_PWR_LVL0]
-#define SQ_CLUSTER_PWR_STATE(state)    (state)->pwr_domain_state[SQ_PWR_LVL1]
-#define SQ_SYSTEM_PWR_STATE(state)     ((PLAT_MAX_PWR_LVL > SQ_PWR_LVL1) ?\
-                               (state)->pwr_domain_state[SQ_PWR_LVL2] : 0)
-
 uintptr_t sq_sec_entrypoint;
 
 int sq_pwr_domain_on(u_register_t mpidr)
 {
+#if SQ_USE_SCMI_DRIVER
+       sq_scmi_on(mpidr);
+#else
        /*
         * SCP takes care of powering up parent power domains so we
         * only need to care about level 0
         */
        scpi_set_sq_power_state(mpidr, scpi_power_on, scpi_power_on,
                                 scpi_power_on);
+#endif
 
        return PSCI_E_SUCCESS;
 }
@@ -70,6 +64,7 @@ void sq_pwr_domain_on_finish(const psci_power_state_t *target_state)
        sq_gic_cpuif_enable();
 }
 
+#if !SQ_USE_SCMI_DRIVER
 static void sq_power_down_common(const psci_power_state_t *target_state)
 {
        uint32_t cluster_state = scpi_power_on;
@@ -97,10 +92,15 @@ static void sq_power_down_common(const psci_power_state_t *target_state)
                                 cluster_state,
                                 system_state);
 }
+#endif
 
 void sq_pwr_domain_off(const psci_power_state_t *target_state)
 {
+#if SQ_USE_SCMI_DRIVER
+       sq_scmi_off(target_state);
+#else
        sq_power_down_common(target_state);
+#endif
 }
 
 void __dead2 sq_system_off(void)
@@ -135,6 +135,9 @@ void __dead2 sq_system_off(void)
 
 void __dead2 sq_system_reset(void)
 {
+#if SQ_USE_SCMI_DRIVER
+       sq_scmi_sys_reboot();
+#else
        uint32_t response;
 
        /* Send the system reset request to the SCP */
@@ -147,6 +150,7 @@ void __dead2 sq_system_reset(void)
        wfi();
        ERROR("SQ System Reset: operation not handled.\n");
        panic();
+#endif
 }
 
 void sq_cpu_standby(plat_local_state_t cpu_state)